package cloud.dao;

import cloud.beans.Anime;
import cloud.config.CacheController;

import com.google.appengine.api.datastore.*;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Classe implémentant l'interface UtilisateurDao @see {@link AnimeDao}
 * @author Alexis JULIEN & R&eacute;mi OGNARD pour TERCA
 * @version 1.0
 */
public class AnimeDao {
	
	/**
	 * L'objet permettant de faire le lien avec la table.
	 */
	private DatastoreService datastore;
	
	
	/**
	 * Emsemble des erreurs produites.
	 */
	private ArrayList<String> erreursDAO;
	
	public AnimeDao() {
		
		this.datastore = DatastoreServiceFactory.getDatastoreService();
		erreursDAO = new ArrayList<String>();
		
	}
		
	/** Implémentation de la méthode définie dans l'interface UtilisateurDao 
	 * @see {@link AnimeDao#creer(Utilisateur)}
	*/
	public boolean creer( Anime anime ) throws DAOException {
		
		//create Entity type "Anime"
		Entity animeEntity = new Entity("Anime");
		
		//set Entity properties to Anime
		animeEntity.setProperty("name", anime.getName());
		animeEntity.setProperty("synopsis", new Text(anime.getSynopsis()));
		animeEntity.setProperty("pathImg", anime.getPathImg());
		
		//save Entity to the datastore
		datastore.put(animeEntity);
		//save Entity in MemCache
		CacheController.put("anime", anime);
		
		return true;
	}
	
	/* Implémentation de la méthode définie dans l'interface UtilisateurDao */
    public Anime trouver( long id ) {

    	Anime anime = new Anime();
    	
    	//gets the Object in MemCache if it exists
    	if(CacheController.containsKey(id)) {
    		System.out.println("recupere dans le cache");
    		anime = (Anime) CacheController.get(id);
    	}
    	
    	//else gets the Object in Datastore 
    	else {
    		System.out.println("recupere dans le datastore");
    		try {
        		Key key = KeyFactory.createKey("Anime", id);
        		Entity result = datastore.get(key);
    	    	anime = map( result );
    	    	
    	    	//save Entity to the MemCache
    	    	CacheController.put(result.getKey().getId(), anime);
        	}
        	 catch ( SQLException | EntityNotFoundException e ) {
    			erreursDAO.add( e.getMessage() );
    		}
    	}
    	return anime;
    }

	/* Implémentation de la méthode définie dans l'interface UtilisateurDao */
    public List<Anime> lister() {
    	
    	List<Anime> animeList = new ArrayList<Anime>();
    	Anime anime;
    		
    	try {
    		Query query = new Query("Anime");
	    	List<Entity> results = datastore.prepare(query).asList(FetchOptions.Builder.withDefaults());  	
	    	
	    	for(Entity result : results){   
	    		anime = map(result);
	    		//save Entity to the MemCache
	    		CacheController.put(result.getKey().getId(), anime);
	    		animeList.add(anime);
	    	}
    	}
    	 catch ( SQLException e ) {
 			erreursDAO.add( e.getMessage() );
 		}
	    	
	    return animeList;
    } 
    
	/**
	* Simple méthode utilitaire permettant de faire la correspondance (le
	* mapping) entre une ligne issue de la table des utilisateurs (un
	* ResultSet) et un bean Utilisateur.
	*/
	private static Anime map( Entity result ) throws SQLException {
		
		Anime anime = new Anime();
		
		anime.setId( result.getKey().getId() );
		anime.setName( (String) result.getProperty("name") );
		Text text = (Text) result.getProperty("synopsis");
		anime.setSynopsis( text.getValue() );
		anime.setPathImg( (String) result.getProperty("pathImg"));

		return anime;
	}

}
